home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 185_01 / hsh.c < prev    next >
Text File  |  1985-08-19  |  25KB  |  863 lines

  1. /* hsh -- ZCPR3 history shell                                               */
  2. /* copyright 1985  Michael M Rubenstein                                     */
  3.  
  4. /* version 1.1  6 Oct 85                                                    */
  5.  
  6. /* Modifications                                                            */
  7.  
  8. /* 1.1      (MMR) Fixed handling of firsthist on wrap around.  Previous     */
  9. /*          did not reset to 0, which could result in the program hanging   */
  10. /*          if a search was done for a leading string which was not in the  */
  11. /*          history.                                                        */
  12.  
  13. #include <sysio.h>
  14. #include <fcb.h>
  15.  
  16. #define SHNAME          "HSH.COM"       /* default name */
  17. #define VARFILE         "HSH.VAR"       /* history file */
  18. #define DEFNHIST        10              /* default number of history lines */
  19.  
  20. /* some interesting characters                                              */
  21. #define CTL             0x1f
  22. #define NUL             0
  23. #define CTLA            (CTL & 'A')
  24. #define CTLC            (CTL & 'C')
  25. #define CTLD            (CTL & 'D')
  26. #define CTLE            (CTL & 'E')
  27. #define CTLF            (CTL & 'F')
  28. #define CTLG            (CTL & 'G')
  29. #define BEL             CTLG
  30. #define BS              (CTL & 'H')
  31. #define CTLJ            (CTL & 'J')
  32. #define LF              CTLJ
  33. #define CR              (CTL & 'M')
  34. #define CTLL            (CTL & 'L')
  35. #define CTLP            (CTL & 'P')
  36. #define CTLQ            (CTL & 'Q')
  37. #define CTLR            (CTL & 'R')
  38. #define CTLS            (CTL & 'S')
  39. #define CTLT            (CTL & 'T')
  40. #define CTLU            (CTL & 'U')
  41. #define CTLV            (CTL & 'V')
  42. #define CTLW            (CTL & 'W')
  43. #define CTLX            (CTL & 'X')
  44. #define CTLY            (CTL & 'Y')
  45. #define CTLZ            (CTL & 'Z')
  46. #define ESC             (CTL & '[')
  47. #define DEL             0x7f
  48.  
  49. extern unsigned         z3env;          /* pointer to ZCPR3 environment */
  50. extern FCB              dfcb_;          /* default CP/M FCB */
  51.  
  52. int                     curdir = FALSE;     /* if TRUE, search current dir */
  53. int                     nhist = DEFNHIST;   /* number of history lines */
  54. int                     firsthist = 0;      /* index of first history line */
  55. int                     lasthist = 0;       /* index of one past last line */
  56. int                     drive, user;        /* current drive/user */
  57. int                     rdrive, ruser;      /* root drive/user */
  58. int                     linepos;            /* position on CRT line */
  59. int                     maxpos;             /* max pos on CRT line used */
  60. int                     maxcols;            /* columns on CRT display */
  61. char                    *cur;               /* pointer to current char in */
  62.                                             /* line being edited */
  63. char                    *line;              /* pointer to start of line */
  64.                                             /* being edited */
  65. char                    *maxcur;            /* end of line */
  66.  
  67. char                    *gethline();        /* get a line from the history */
  68. char                    *puthline();        /* put a line to the history */
  69.  
  70. FCB                     *gefcb();       /* get ZCPR3 external FCB */
  71. char                    *getcrt();      /* get ZCPR3 terminal data */
  72.  
  73. main()
  74. {
  75.   static FCB            *efcb;          /* FCB for shell name */
  76.   static char           shname[13];     /* shell name */
  77.   static char           *s;
  78.   int                   du;
  79.   static int            c;
  80.   static int            i;
  81.   static int            n = -1;         /* value of command line arg */
  82.   char                  aline[256];
  83.  
  84.   line = aline;                         /* cheap way to allocate mem */
  85.   maxcur = line + 255;                  /* end of line */
  86.  
  87.   /* if there is a command line argument, evaluate and save it */
  88.   if (isdigit(dfcb_.name1.fname[0]))
  89.   {
  90.     n = atoi(dfcb_.name1.fname);
  91.     if (n < 0)
  92.       error("hsh: number of history lines too large.");
  93.   }
  94.   else
  95.   if (dfcb_.name1.fname[0] != ' ')
  96.     error("syntax:  hsh [<number of history lines to keep>]");
  97.  
  98.  
  99.   if (z3env == 0)
  100.     error("hsh: ZCPR3 required.");
  101.  
  102.   /* clear external command line.  abort if none */
  103.   if (!clcl())
  104.     error("hsh: ZCPR3 external command line required.");
  105.  
  106.   /* find where we are and where root dir is for later use */
  107.   drive = curdsk();
  108.   user = getusr();
  109.   du = groot();
  110.   rdrive = du >> 8;
  111.   ruser = du & 8;
  112.  
  113.   /* if not invoked as a shell, install as shell */
  114.   if (!qsh())
  115.   {
  116.     /* if no external FCB, use default name */
  117.     if ((efcb = gefcb()) == NULL)
  118.     {
  119.       setfcb(SHNAME, &dfcb_);
  120.       efcb = &dfcb_;
  121.     }
  122.  
  123.     /* find where program is and set up name with drive/user */
  124.     if ((du = pfnd(efcb, curdir)) == -1)
  125.       error("hsh: Cannot find shell program.");
  126.     shname[0] = (du >> 8) + 'A';
  127.     du &= 0xff;
  128.     shname[1] = du / 10 + '0';
  129.     shname[2] = du % 10 + '0';
  130.     shname[3] = ':';
  131.     for (i = 0; i < 8; ++i)
  132.     {
  133.       if ((c = (efcb->name1.fname[i] & 0x7f)) == ' ')
  134.         break;
  135.       shname[4 + i] = c;
  136.     }
  137.     shname[4 + i] = '\0';
  138.     if (shpsh(shname))
  139.       error("hsh: Cannot install shell.");
  140.  
  141.     ps("HSH Version 1.0 (1 Oct 85) installed\r\n");
  142.  
  143.     /* if a command line arg was entered, set up history file with number */
  144.     /* of lines to keep */
  145.     if (n >= 0)
  146.     {
  147.       nhist = n;
  148.     /* go to the right place */
  149.       select(rdrive);
  150.       setusr(ruser);
  151.       setfcb(VARFILE, &dfcb_);
  152.       delete(&dfcb_);
  153.       if (make(&dfcb_) == 0xff)
  154.         sherror("hsh: Cannot create HSH.VAR.");
  155.       puthist();
  156.     }
  157.  
  158.     /* exit after installing shell, so will work from submit file */
  159.     return;
  160.   }
  161.  
  162.   /* set ZCPR3 command status message so next program won't think it's */
  163.   /* a shell (needed since we don't warm boot on exit) */
  164.   pcst(0);
  165.  
  166.   maxcols = *getcrt() & 0xff;
  167.  
  168.   gethist();                            /* get history */
  169.   getcmd();                             /* handle a command */
  170.   puthist();                            /* save history */
  171. }
  172.  
  173. /* get the history                                                          */
  174. gethist()
  175. {
  176.   /* first record in history file keeps parameters */
  177.   struct {              int     f_nhist, f_fhist, f_lhist;
  178.                         char    f_fill[126];
  179.          }              fnhist;
  180.  
  181.   /* go to the right place */
  182.   select(rdrive);
  183.   setusr(ruser);
  184.   setfcb(VARFILE, &dfcb_);
  185.  
  186.   /* if there's a history file, read it in and set firsthist and lasthist */
  187.   if (open(&dfcb_) != 0xff)
  188.   {
  189.     setdma(&fnhist);
  190.     if (!rdseq(&dfcb_))
  191.     {
  192.       nhist = fnhist.f_nhist;
  193.       firsthist = fnhist.f_fhist;
  194.       lasthist = fnhist.f_lhist;
  195.     }
  196.   }
  197.   else
  198.     /* if no history file, create it */
  199.     if (make(&dfcb_) == 0xff)
  200.       sherror("hsh: Cannot create HSH.VAR.");
  201. }
  202.  
  203. /* put the history paramters to file                                        */
  204. puthist()
  205. {
  206.   /* first record in history file keeps parameters */
  207.   struct {              int     f_nhist, f_fhist, f_lhist;
  208.                         char    f_fill[126];
  209.          }              fnhist;
  210.  
  211.   fnhist.f_nhist = nhist;
  212.   fnhist.f_fhist = firsthist;
  213.   fnhist.f_lhist = lasthist;
  214.  
  215.   setdma(&fnhist);
  216.   dfcb_.rrec = 0;
  217.   if (wrran(&dfcb_))
  218.     sherror("hsh: Error writing HSH.VAR.");
  219.  
  220.   if (close(&dfcb_) == 0xff)
  221.     sherror("hsh: Error closing HSH.VAR");
  222.  
  223.   /* return to where we were */
  224.   select(drive);
  225.   setusr(user);
  226. }
  227.  
  228. /* get a history line.  returns pointer to line for convenience.            */
  229. char *gethline(line, n)
  230.   char                  *line;
  231.   int                   n;
  232. {
  233.   dfcb_.rrec = 2 * n + 1;
  234.   setdma(line);
  235.   if (rdran(&dfcb_))
  236.     sherror("hsh: Cannot read HSH.VAR.");
  237.  
  238.   ++dfcb_.rrec;
  239.   setdma(line + 128);
  240.   if (rdran(&dfcb_))
  241.     sherror("hsh: Cannot read HSH.VAR.");
  242.   return line;
  243. }
  244.  
  245. /* put a history line.  returns pointer to line for convenience.            */
  246. char *puthline(line, n)
  247.   char